/*
 * @(#)DrawAssImpl.java   09/09/13
 *
 * Copyright (C) 2009 Ecole des Mines d'Ales
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact: yulinz88@gmail.com
 *
 *
 *
 */



package fr.ema.arch3d.gea.ass;

import fr.ema.arch3d.ref.Fractal;

import org.jgraph.JGraph;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.GraphLayoutCache;
import org.jgraph.graph.GraphModel;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;

/**
 * Class description
 *
 *
 * @version        1.0, 09/09/13
 * @author         Huaxi (Yulin) ZHANG
 */
public class DrawAssImpl {

    /** Field description */
    public static DefaultGraphCell[] cells = null;

    /** Field description */
    public static DefaultEdge e[] = null;

    /** Field description */
    public static JScrollPane aGraph;

    /** Field description */
    public static JTextPane aText;

    /** Field description */
    public static JScrollPane aTree;

    /** Field description */
    public static Component container;

    /** Field description */
    public static JGraph graph;

    public JSplitPane drawAss(Component container) {
        this.container = container;

        GraphModel model = new DefaultGraphModel();

        /*
         * GraphLayoutCache view = new GraphLayoutCache(model,
         * new DefaultCellViewFactory());
         */
        GraphLayoutCache view = new GraphLayoutCache(model, (new ASCellViewFactory()));

        graph = new JGraph(model, view);

        // draw vertext
        DrawVertexComponent dvcmp = new DrawVertexComponent();
        DrawVertexConnector dvctr = new DrawVertexConnector();
        List                cmps  = new ArrayList();
        List                ctrs  = new ArrayList();

        try {
            Component[] cs = Fractal.getContentController(container).getFcSubComponents();

            for (int i = 0; i < cs.length; i++) {
                Component c2 = cs[i];

                if (Fractal.getElementtypeController(c2).getElementType().equals("component")) {
                    cmps.add(cs[i]);
                }

                if (Fractal.getElementtypeController(c2).getElementType().equals("connector")) {
                    ctrs.add(cs[i]);
                }
            }

            cells = new DefaultGraphCell[cmps.size() + ctrs.size()];

            for (int i = 0; i < cells.length; i++) {

                // if(Fractal.getElementtypeController(cs[i]).getElementType().equals("component"))
                if (i < cmps.size()) {
                    cells[i] = dvcmp.drawVertext((Component) cmps.get(i), i);

                    // GraphConstants.setAutoSize(cells[i].getAttributes(),true);
                } else {
                    cells[i] = dvctr.drawVertextConnector((Component) ctrs.get(i - cmps.size()), i - cmps.size());
                }
            }
        } catch (NoSuchInterfaceException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // draw edges
        DrawEdgeAss de = new DrawEdgeAss();

        // MyEdge[] edges=new MyEdge[ctrs.size()];
        List esn = new ArrayList();
        List es  = new ArrayList();

        for (int i = 0; i < ctrs.size(); i++) {
            es = de.drawEdge(cells, (Component) ctrs.get(i));

            for (int j = 0; j < es.size(); j++) {
                esn.add(es.get(j));
            }
        }

        e = new DefaultEdge[esn.size()];

        for (int i = 0; i < e.length; i++) {
            e[i] = (DefaultEdge) esn.get(i);
        }

        graph.getGraphLayoutCache().insert(cells);
        graph.getGraphLayoutCache().insert(e);
        graph.setPortsVisible(true);
        aGraph = new JScrollPane(graph);

        MyTreeAss tree = new MyTreeAss(model);

        aTree = new JScrollPane(tree.s);

        // graph.getModel().addGraphModelListener(gtModel);
        // tree.setRootVisible(false);
        AdlTextAss t = new AdlTextAss();

        aText = new JTextPane();
        aText.setDocument(t.createTextAss(container));
        aText.setEditable(false);

        JSplitPane pane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, aTree, aGraph);
        JSplitPane pane  = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pane1, aText);

        graph.addMouseListener(new MouseEventAss(this));
        pane.setSize(1100, 300);
        pane1.setDividerLocation(180);
        pane.setDividerLocation(900);

        return pane;
    }

    /**
     *
     * @param CmpName: the deleted, added or replaced component name
     * @param type: the evolution type: delete, add or replace
     */
    public static void refreshContainerGraph(String cmpName, String type) {
        DefaultGraphCell[] cells1 = null;

        // draw new assembly
        DrawVertexComponent dvcmp = new DrawVertexComponent();
        DrawVertexConnector dvctr = new DrawVertexConnector();
        List                cmps  = new ArrayList();
        List                ctrs  = new ArrayList();

        // draw vertex: components and connectors
        try {
            Component[] cs = Fractal.getContentController(container).getFcSubComponents();

            for (int i = 0; i < cs.length; i++) {
                Component c2 = cs[i];

                if (Fractal.getElementtypeController(c2).getElementType().equals("component")) {
                    cmps.add(cs[i]);
                }

                if (Fractal.getElementtypeController(c2).getElementType().equals("connector")) {
                    ctrs.add(cs[i]);

                    for (int j = 0; j < cs[i].getFcInterfaces().length; j++) {}
                }
            }

            cells1 = new DefaultGraphCell[cmps.size() + ctrs.size()];

            for (int i = 0; i < cells1.length; i++) {

                // if(Fractal.getElementtypeController(cs[i]).getElementType().equals("component"))
                if (i < cmps.size()) {
                    cells1[i] = dvcmp.drawVertext((Component) cmps.get(i), i);
                }

                // GraphConstants.setAutoSize(cells[i].getAttributes(),true);
                else {
                    cells1[i] = dvctr.drawVertextConnector((Component) ctrs.get(i - cmps.size()), i - cmps.size());
                }
            }
        } catch (NoSuchInterfaceException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // draw edges
        DrawEdgeAss drawEdge = new DrawEdgeAss();
        DefaultEdge e1[];
        List        esn = new ArrayList();
        List        es  = new ArrayList();

        for (int i = 0; i < ctrs.size(); i++) {
            es = drawEdge.drawEdge(cells1, (Component) ctrs.get(i), cmpName);

            for (int j = 0; j < es.size(); j++) {
                esn.add(es.get(j));
            }
        }

        e1 = new DefaultEdge[esn.size()];

        for (int i = 0; i < e1.length; i++) {
            e1[i] = (DefaultEdge) esn.get(i);
        }

        // graph.getGraphLayoutCache().
        graph.getGraphLayoutCache().remove(cells, true, true);

        // graph.getGraphLayoutCache().remove(e);
        // graph.removeAll();
        graph.getGraphLayoutCache().insert(cells1);
        graph.getGraphLayoutCache().insert(e1);
        graph.setPortsVisible(true);
        aGraph.updateUI();
    }
}
